package com.bigdata

import scala.io.Source

object Demo27Match {

  def main(args: Array[String]): Unit = {
    /**
     * 模式匹配
     * java中的模式匹配可以匹配基本数据类型，字符串，枚举
     *
     * scala的模式匹配，可以匹配基本数据类型，字符串，对象，元组，数组，匹配类型
     */

    /**
     * 1、匹配基本数据类型
     *
     * 模式匹配只有一个能匹配成功
     * 下划线代表其其它情况
     * 在写代码是需要考虑到所有的情况
     */
    val num: Int = 8
    num match {
      case 8 =>
        println(8)
      case 9 =>
        println(9)
      case _ =>
        println("defalut")
    }


    val str: String = "aaa"
    str match {
      case "aaa" =>
        println("111")
      case _ =>
        println(str)
    }

    /**
     * 3、匹配元组
     */
    val t: (String, Int, String) = ("张三", 23, "001")

    t match {
      case (name: String, age: Int, no: String) => {
        println(s"name:$name---age:$age---no:$no")
      }
    }


    /**
     * 4、匹配数组
     */
    val array: Array[String] = Array("001", "李四", "篮球", "hello")

    array match {
      case Array(no: String, name: String) => {
        println(s"no:$no---name:$name")
      }
      case Array(no: String, name: String, like: String) => {
        println(s"no:$no---name:$name---like:$like")
      }
      case _ => {
        println("无法匹配！！！")
      }
    }


    /**
     * 5、匹配类型
     * 多态，父类引用指向子类的实例
     */
    val obj: Any = true

    obj match {
      case i: Int =>
        println(s"int---$i")
      case flag: Boolean =>
        println(s"Boolean---$flag")
      case _ =>
        println("其他的数类型")
    }

    // 匹配自定义的数据类型，样例类支持模式匹配的语法
    val stu: Person = Person(100, "zs")


    stu match {
      case Person(id: Int, name: String, age: Int) =>
        println(s"$id---$name---$age")
      case _ =>
        println("其他的数类型")
    }

    /**
     * 模式匹配可以有返回值
     * 判断数字是奇数还是偶数，并且返回判断的结果
     */
    val num1: Int = 98

    val result: String = num1 % 2 match {
      case 0 =>
        "偶数"
      case 1 =>
        "奇数"
    }
    println(result)

    /**
     * 模式匹配在map集合的使用
     */
    val map = Map("001" -> "张三", "002" -> "李四")
    //    map.get("001") // Some or None
    val key: String = "001"
    val value = map.get(key) match {
      case Some(v) =>
        v
      case None =>
        "未命名"
    }
    println(value)

    //    val name: String = map.getOrElse("003", "未命名")
    //    println(name)


    //    /**
    //     * 模式匹配结合函数的使用
    //     */
    val lines: List[String] = Source.fromFile("data/students.txt").getLines().toList

//    lines.map {
    //      case str: String =>
    //        println(str)
    //    }


    val stuMap: List[(String, String)] = lines.map(line => {
      val array: Array[String] = line.split(",")
      (array.head, array(1))
    })

    stuMap.map {
      case (id: String, name: String) =>
        println(s"$id --- $name")
    }

    //按照逗号分割数据
    val arrays: List[Array[String]] = lines.map(line => line.split(","))

    // 从数组中在获取值的时候，不需要查看元数据，指定根据字段的名称就知道使用的是哪个字段
    val tuples: List[(String, String, String, String, String)] = arrays.map {
      case Array(id: String, name: String, age: String, gender: String, clazz: String) =>
        (id, name, age, gender, clazz)
    }

    tuples.foreach(println)

  }

}

// 在底层编译为class文件时，还是一个普通的class文件，但是scala编译器会在里面添加很多工具代码
case class Person(id: Int, name: String, age: Int = 20)

